module.exports = function (hljs) {
  return {
    keywords: {
      literal: 'true false null',
      keyword:
            'byte short char int long boolean float double void ' +
            // groovy specific keywords
            'def as in assert trait ' +
            // common keywords with Java
            'super this abstract static volatile transient public private protected synchronized final ' +
            'class interface enum if else for while switch case break default continue ' +
            'throw throws try catch finally implements extends new import package return instanceof'
    },

    contains: [
      hljs.COMMENT(
        '/\\*\\*',
        '\\*/',
        {
          relevance: 0,
          contains: [
            {
              // eat up @'s in emails to prevent them to be recognized as doctags
              begin: /\w+@/, relevance: 0
            },
            {
              className: 'doctag',
              begin: '@[A-Za-z]+'
            }
          ]
        }
      ),
      hljs.C_LINE_COMMENT_MODE,
      hljs.C_BLOCK_COMMENT_MODE,
      {
        className: 'string',
        begin: '"""',
        end: '"""'
      },
      {
        className: 'string',
        begin: "'''",
        end: "'''"
      },
      {
        className: 'string',
        begin: '\\$/',
        end: '/\\$',
        relevance: 10
      },
      hljs.APOS_STRING_MODE,
      {
        className: 'regexp',
        begin: /~?\/[^\/\n]+\//,
        contains: [
          hljs.BACKSLASH_ESCAPE
        ]
      },
      hljs.QUOTE_STRING_MODE,
      {
        className: 'meta',
        begin: '^#!/usr/bin/env',
        end: '$',
        illegal: '\n'
      },
      hljs.BINARY_NUMBER_MODE,
      {
        className: 'class',
        beginKeywords: 'class interface trait enum',
        end: '{',
        illegal: ':',
        contains: [
          { beginKeywords: 'extends implements' },
          hljs.UNDERSCORE_TITLE_MODE
        ]
      },
      hljs.C_NUMBER_MODE,
      {
        className: 'meta', begin: '@[A-Za-z]+'
      },
      {
        // highlight map keys and named parameters as strings
        className: 'string', begin: /[^\?]{0}[A-Za-z0-9_$]+ *:/
      },
      {
        // catch middle element of the ternary operator
        // to avoid highlight it as a label, named parameter, or map key
        begin: /\?/, end: /\:/
      },
      {
        // highlight labeled statements
        className: 'symbol',
        begin: '^\\s*[A-Za-z0-9_$]+:',
        relevance: 0
      }
    ],
    illegal: /#|<\//
  }
}
